package com.besttone.search;

import java.io.InputStream;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.amap.cn.apis.util.ConstantsAmap;
import com.amap.mapapi.core.AMapException;
import com.amap.mapapi.geocoder.Geocoder;
import com.amap.mapapi.location.LocationManagerProxy;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.location.Address;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.os.Bundle;
import android.os.Handler;
import android.os.IInterface;
import android.os.Message;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

public class Client
{
	// -------------------------------------------------------------------------
	private static Client instance;
	private static String screenSize = "";
	private static String deviceId = "";
	private static float dencyRate = 1.0f;
	private static DisplayMetrics display;

	private Handler mHd;
	private ThreadPoolExecutor mThreadPoorForLocal;
	private ThreadPoolExecutor mThreadPoorForDownload;
	private ThreadPoolExecutor mThreadPoorForRequest;
	private Context mContext;

	private final static String Tag = "Client";

	private Geocoder coder;
	private String addressName;
	private LocationManagerProxy locationManager = null;

	public String area;
	public String cityName;
	private GetLocationAdressListener mLoactionDlistener = null;
	
	public boolean bChangeCity=true;
	
	public final String iflytech_APP_ID = "508eafc2";

	public void setmLoactionDlistener(GetLocationAdressListener mLoactionDlistener)
	{
		this.mLoactionDlistener = mLoactionDlistener;
	}

	// -------------------------------------------------------------------------
	private Client()
	{
		instance = this;
		mHd = new Handler();
		mThreadPoorForLocal = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
		mThreadPoorForRequest = new ThreadPoolExecutor(4, 8, 15, TimeUnit.SECONDS,
				new ArrayBlockingQueue<Runnable>(100));
		mThreadPoorForDownload = new ThreadPoolExecutor(2, 5, 5, TimeUnit.SECONDS,
				new ArrayBlockingQueue<Runnable>(100));
	}

	// -------------------------------------------------------------------------
	public static void release()
	{
		try
		{
			instance.mThreadPoorForLocal.shutdownNow();
			instance.mThreadPoorForRequest.shutdownNow();
			instance.mThreadPoorForDownload.shutdownNow();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		instance = null;
	}

	// -------------------------------------------------------------------------
	public static Client getInstance()
	{
		if (instance == null)
		{
			instance = new Client();
		}
		return instance;
	}

	// -------------------------------------------------------------------------
	public static Handler getHandler()
	{
		return getInstance().mHd;
	}

	// -------------------------------------------------------------------------
	public static void postRunnable(Runnable r)
	{
		getInstance().mHd.post(r);
	}

	// -------------------------------------------------------------------------
	public static ThreadPoolExecutor getThreadPoolForLocal()
	{
		return getInstance().mThreadPoorForLocal;
	}

	// -------------------------------------------------------------------------
	public static ThreadPoolExecutor getThreadPoolForRequest()
	{
		Log.d(Tag, "request");
		return getInstance().mThreadPoorForRequest;
	}

	// -------------------------------------------------------------------------
	public static ThreadPoolExecutor getThreadPoolForDownload()
	{
		return getInstance().mThreadPoorForDownload;
	}

	// -------------------------------------------------------------------------
	public static void initWithContext(Context context)
	{
		getInstance().mContext = context;
		display = new DisplayMetrics();
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		if (null != wm)
		{
			wm.getDefaultDisplay().getMetrics(display);
			screenSize = display.widthPixels < display.heightPixels ? display.widthPixels + "x" + display.heightPixels
					: display.heightPixels + "x" + display.widthPixels;
			dencyRate = display.density / 1.5f;
		}
		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		if (null != tm)
		{
			deviceId = tm.getDeviceId();
			if (null == deviceId)
				deviceId = "";
		}

		getInstance().locationManager = LocationManagerProxy.getInstance(Client.getContext());
	}

	// -------------------------------------------------------------------------
	public static Context getContext()
	{
		return getInstance().mContext;
	}

	// -------------------------------------------------------------------------
	public static String getDeviceId()
	{
		return deviceId;
	}

	// -------------------------------------------------------------------------
	public static String getScreenSize()
	{
		return screenSize;
	}

	// -------------------------------------------------------------------------
	public static float getDencyParam()
	{
		return dencyRate;
	}

	// -------------------------------------------------------------------------
	public static DisplayMetrics getDisplayMetrics()
	{
		return display;
	}

	// -------------------------------------------------------------------------
	public static boolean decetNetworkOn()
	{
		try
		{
			ConnectivityManager cm = (ConnectivityManager) getInstance().mContext
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			if (null != cm)
			{
				NetworkInfo wi = cm.getActiveNetworkInfo();
				if (null != wi)
					return wi.isConnected();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return false;
	}

	public static boolean decetNetworkOn(Context c)
	{
		ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (null != cm)
		{
			NetworkInfo info = cm.getActiveNetworkInfo();
			if (null != info)
				return info.isConnected();
		}
		return false;
	}

	public static Bundle getAppInfoBundle(Context context)
	{
		Bundle bundle = null;
		try
		{
			ApplicationInfo appInfo = ((Activity) context).getPackageManager().getApplicationInfo(
					((Activity) context).getPackageName(), PackageManager.GET_META_DATA);
			if (appInfo != null)
			{
				bundle = appInfo.metaData;

			}
			PackageInfo pinfo = ((Activity) context).getPackageManager().getPackageInfo(
					((Activity) context).getPackageName(), PackageManager.GET_CONFIGURATIONS);
			if (pinfo != null)
			{
				bundle.putString("versionName", pinfo.versionName);
				bundle.putInt("versionCode", pinfo.versionCode);
			}
		}
		catch (NameNotFoundException e)
		{
			e.printStackTrace();
		}

		return bundle;
	}

	/**
	 * 应用程序版本
	 * 
	 * @param context
	 * @return
	 */
	public static String getVersion(Context context)
	{
		String uVersion = "";
		Bundle bundle = getAppInfoBundle(context);
		if (bundle != null)
		{
			uVersion = bundle.getString("versionName");
		}
		return uVersion;
	}

	// 高德定位

	// 地理编码
	public void getAddress(final double mLat, final double mLon)
	{
		this.getThreadPoolForRequest().execute(new Runnable()
		{
			public void run()
			{
				try
				{
					coder = new Geocoder(Client.getContext());
					List<Address> address = coder.getFromLocation(mLat, mLon, 3);
					Log.d("adress", "" + address.size());
					if (address != null && address.size() > 0)
					{
						Address addres = address.get(0);
						addressName = addres.getAdminArea() + addres.getSubLocality() + addres.getFeatureName() + "附近";

						String ad = addres.getAdminArea();
						String su = addres.getSubLocality();
						if (ad.contains("市"))
							area = ad;
						else
							area = su;
						Log.d("adress", "" + addressName);
						Log.d("area", "" + area);

						mLoactionDlistener.onGetLocationAdress();
					}
				}
				catch (AMapException e)
				{
					// TODO Auto-generated catch block
					Log.e("adress", ""+e.toString());
//					mLoactionDlistener.onFialedGetLocationAdress();
				}
				catch (Exception e)
				{
					// TODO Auto-generated catch block
					Log.e("adress", ""+e.toString());
//					mLoactionDlistener.onFialedGetLocationAdress();
				}

			}
		});

	}
	
	public void tryGetAddress(final double mLat, final double mLon)
	{
		this.getThreadPoolForRequest().execute(new Runnable()
		{
			public void run()
			{
				try
				{
					coder = new Geocoder(Client.getContext());
					List<Address> address = coder.getFromLocation(mLat, mLon, 3);
					Log.d("adress", "" + address.size());
					if (address != null && address.size() > 0)
					{
						Address addres = address.get(0);
						addressName = addres.getAdminArea() + addres.getSubLocality() + addres.getFeatureName() + "附近";
						
						Log.d("adress", "" + addressName);
						Log.d("area", "" + area);
					}
				}
				catch (AMapException e)
				{
					// TODO Auto-generated catch block
					Log.e("adress", ""+e.toString());
					mLoactionDlistener.onFialedGetLocationAdress();
				}
				catch (Exception e)
				{
					// TODO Auto-generated catch block
					Log.e("adress", ""+e.toString());
					mLoactionDlistener.onFialedGetLocationAdress();
				}

			}
		});

	}

	public boolean enableMyLocation()
	{
		boolean result;
		result = true;
		try
		{
			Criteria cri = new Criteria();
			cri.setAccuracy(Criteria.ACCURACY_COARSE);
			cri.setAltitudeRequired(false);
			cri.setBearingRequired(false);
			cri.setCostAllowed(false);
			String bestProvider = locationManager.getBestProvider(cri, true);
			Log.d("bestProvider",bestProvider);
			locationManager.requestLocationUpdates(bestProvider, 60000, 100, locationListener);
			
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public void disableMyLocation()
	{
		try
		{
			locationManager.removeUpdates(locationListener);
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	LocationListener locationListener = new LocationListener()
	{

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras)
		{
			// TODO Auto-generated method stub

		}

		@Override
		public void onProviderEnabled(String provider)
		{
			// TODO Auto-generated method stub

		}

		@Override
		public void onProviderDisabled(String provider)
		{
			// TODO Auto-generated method stub
			Toast.makeText(Client.getContext(), "定位失败，请检查网络和GPS", Toast.LENGTH_SHORT);

		}

		@Override
		public void onLocationChanged(Location location)
		{
			// TODO Auto-generated method stub
			if (location != null)
			{
				Double geoLat = location.getLatitude();
				Double geoLng = location.getLongitude();
				String str = ("定位成功:(" + geoLat + "," + geoLng + ")");
				Message msg = new Message();
				msg.obj = str;

				Log.d("location",str);
//				getAddress(30.783298, 120.376826);
//				getAddress(38.844814, 105.706442);//阿拉善盟
//				getAddress(52.335262, 124.711526);//大兴安岭地区
//				getAddress(42.904823, 129.513228);//延边朝鲜族自治州
				getAddress(geoLat,geoLng);
			}
		}
	};

	public static interface GetLocationAdressListener
	{
		public void onGetLocationAdress();
		public void onFialedGetLocationAdress();
	}
	
	/**
	 * 读取语法文件
	 * @return
	 */
	public static String readAbnfFile()
	{
		int len = 0;
		byte []buf = null;
		String grammar = "";
		try {
			InputStream in = getContext().getAssets().open("gm_continuous_digit.abnf");			
			len  = in.available();
			buf = new byte[len];
			in.read(buf, 0, len);
			
			grammar = new String(buf,"gbk");
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return grammar;

	}
}
